import {
  document,
	window,
	HTMLCanvasElement,
	requestAnimationFrame,
	cancelAnimationFrame,
core,
	Event,
  Event0
} from "dhtml-weixin"
import * as THREE from './three/Three';
import Stats from './three/addons/libs/stats.module.js';

import { SelectionBox } from './three/addons/interactive/SelectionBox.js';
import { SelectionHelper } from './three/addons/interactive/SelectionHelper.js';

var requestId
Page({
  onShareAppMessage(){
    return getApp().onShare()
  },
  onShareTimeline(){
     return {title:"ThreeX 2.0"}
  },
	onUnload() {
		cancelAnimationFrame(requestId, this.canvas)
		this.worker && this.worker.terminate()
if(this.canvas) this.canvas = null
		setTimeout(() => {
			if (this.renderer instanceof THREE.WebGLRenderer) {
				this.renderer.dispose()
				this.renderer.forceContextLoss()
				this.renderer.context = null
				this.renderer.domElement = null
				this.renderer = null
			}
		}, 0)
	},
  webgl_touch(e){
		const web_e = (window.platform=="devtools"?Event:Event0).fix(e)
		this.canvas.dispatchEvent(web_e)
  },
  onLoad() {
		document.createElementAsync("canvas", "webgl2").then(canvas => {
      this.canvas = canvas
      this.body_load(canvas).then()
    })
  },
  async body_load(canvas3d) {
			let container, stats;
			let camera, scene, renderer;

			init();
			animate();

			function init() {

				container = document.createElement( 'div' );
				document.body.appendChild( container );

				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 500 );
				camera.position.z = 50;

				scene = new THREE.Scene();
				scene.background = new THREE.Color( 0xf0f0f0 );

				scene.add( new THREE.AmbientLight( 0xaaaaaa ) );

				const light = new THREE.SpotLight( 0xffffff, 10000 );
				light.position.set( 0, 25, 50 );
				light.angle = Math.PI / 5;

				light.castShadow = true;
				light.shadow.camera.near = 10;
				light.shadow.camera.far = 100;
				light.shadow.mapSize.width = 1024;
				light.shadow.mapSize.height = 1024;

				scene.add( light );

				const geometry = new THREE.BoxGeometry();

				for ( let i = 0; i < 200; i ++ ) {

					const object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );

					object.position.x = Math.random() * 80 - 40;
					object.position.y = Math.random() * 45 - 25;
					object.position.z = Math.random() * 45 - 25;

					object.rotation.x = Math.random() * 2 * Math.PI;
					object.rotation.y = Math.random() * 2 * Math.PI;
					object.rotation.z = Math.random() * 2 * Math.PI;

					object.scale.x = Math.random() * 2 + 1;
					object.scale.y = Math.random() * 2 + 1;
					object.scale.z = Math.random() * 2 + 1;

					object.castShadow = true;
					object.receiveShadow = true;

					scene.add( object );

				}

				renderer = new THREE.WebGLRenderer( { antialias: true } );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				renderer.shadowMap.enabled = true;
				renderer.shadowMap.type = THREE.PCFShadowMap;

				container.appendChild( renderer.domElement );

				stats = new Stats();
				container.appendChild( stats.dom );

				window.addEventListener( 'resize', onWindowResize );

			}

			function onWindowResize() {

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				renderer.setSize( window.innerWidth, window.innerHeight );

			}

			//

			function animate() {

				requestId = requestAnimationFrame( animate );

				render();
				stats.update();

			}

			function render() {

				renderer.render( scene, camera );

			}

			const selectionBox = new SelectionBox( camera, scene );
			const helper = new SelectionHelper( renderer, 'selectBox' );

			document.addEventListener( 'pointerdown', function ( event ) {

				for ( const item of selectionBox.collection ) {

					item.material.emissive.set( 0x000000 );

				}

				selectionBox.startPoint.set(
					( event.clientX / window.innerWidth ) * 2 - 1,
					- ( event.clientY / window.innerHeight ) * 2 + 1,
					0.5 );

			} );

			document.addEventListener( 'pointermove', function ( event ) {

				if ( helper.isDown ) {

					for ( let i = 0; i < selectionBox.collection.length; i ++ ) {

						selectionBox.collection[ i ].material.emissive.set( 0x000000 );

					}

					selectionBox.endPoint.set(
						( event.clientX / window.innerWidth ) * 2 - 1,
						- ( event.clientY / window.innerHeight ) * 2 + 1,
						0.5 );

					const allSelected = selectionBox.select();

					for ( let i = 0; i < allSelected.length; i ++ ) {

						allSelected[ i ].material.emissive.set( 0xffffff );

					}

				}

			} );

			document.addEventListener( 'pointerup', function ( event ) {

				selectionBox.endPoint.set(
					( event.clientX / window.innerWidth ) * 2 - 1,
					- ( event.clientY / window.innerHeight ) * 2 + 1,
					0.5 );

				const allSelected = selectionBox.select();

				for ( let i = 0; i < allSelected.length; i ++ ) {

					allSelected[ i ].material.emissive.set( 0xffffff );

				}

			} );
  }
})